package edu.gatech.oad.mule;

import java.io.Serializable;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;

import edu.gatech.oad.mule.config.interfaces._ConfigurationPanel;

/**
 * This class represents the game itself. You can think of this as the board in
 * the board game. It does not contain much logic, but rather serves as a holder
 * of all the information GameDriver needs to operate the game properly.
 * 
 * @author Brendan McGarry, Dale Avery, D'Miria Collins, Natasha Parekh, Jaemin
 *         Park
 * @version %I%, %G%
 */
public class Game implements Serializable {

	private static final long serialVersionUID = 606691880660006477L;
	
	private Player[] players;
	private Map worldMap;
	private Map townMap;
	private Map currentMap = null;
	private boolean playing;
	private int round;

	/**
	 * This constructor configures a new Game object using data from a
	 * configuration panel
	 */
	public Game(_ConfigurationPanel panel) {
		System.out.println("game");
		playing = true;
		// Configure players
		players = new Player[panel.getNumberOfPlayers()];
		System.out.println("creating players...");
		System.out.println("players.length: [" + players.length + "]");
		for (int i = 0; i < players.length; i++) {
			System.out.println("i: [" + i + "]");
			players[i] = new Player(i, panel);
			System.out.println(players[i].toString());
		}// end for

		// Configure maps
		townMap = new TownMap(panel);
		worldMap = new WorldMap(panel);
		currentMap = worldMap;
		round = 0;
		System.out.println("/game");
	}// end constructor

	/**
	 * Builds a list of players in which the players are ranked from last to
	 * first place.
	 * 
	 * @return A list of players sorted by score.
	 */
	public Player[] getRankedPlayers() {
		//a swap has not occured yet (optimized bubble sort)
		boolean swap = true;
		//bubble sort
		while(swap){
			swap = false;
			for(int i = 1; i < players.length; i++){
				if(players[i-1].calcScore() > players[i].calcScore()){
					Player tmp = players[i];
					players[i] = players[i-1];
					players[i-1] = tmp;
					swap = true;
				}//end if
			}//end for
		}//end while
		return players;
	}// end method getRankedPlayers

	/**
	 * Getter for game's players.
	 * 
	 * @return The array of Player's in this game.
	 */
	public Player[] getPlayers() {
		return players;
	}// end method getPlayers

	/**
	 * @return The current map
	 */
	public Map getCurrentMap() {
		return currentMap;
	}// end method getCurrentMap

	/**
	 * 
	 * @return This game's town map.
	 */
	public Map getTownMap() {
		return townMap;
	}//end method getTownMap

	/**
	 * 
	 * @return This game's world map.
	 */
	public Map getWorldMap() {
		return worldMap;
	}//end method getWorldMap

	/**
	 * 
	 * @return True if the game is being played, false if it is not.
	 */
	public boolean isPlaying() {
		return playing;
	}//end method isPlaying

	/**
	 * Switches between the world and town maps as the current map
	 */
	public void switchMap() {
		if (currentMap.equals(worldMap)) {
			currentMap = townMap;
		}// end if
		else {
			currentMap = worldMap;
		}// end else
	}// end method switchMap
	
	/**
	 * Transitions to the next round of the game.
	 */
	public void nextRound() {
		round++;
	}//end method nextRound
	
	/**
	 * 
	 * @return The current round number of the game.
	 */
	public int getRound() {
		return round;
	}//end method getRound

}// end class Game
